package xyz.xmh.executor;

import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import reactor.core.publisher.Mono;
import xyz.xmh.dao.file.ReactiveFileDao;
import xyz.xmh.dao.recycle.ReactiveRecycleDao;
import xyz.xmh.pojo.entity.BaseItem;
import xyz.xmh.pojo.enums.CategoryEnum;
import xyz.xmh.pojo.enums.CheckNameEnum;
import xyz.xmh.pojo.request.file.ListRequest;
import xyz.xmh.pojo.request.file.SearchRequest;
import xyz.xmh.pojo.request.file.UpdateRequest;
import xyz.xmh.pojo.response.file.*;

import java.nio.file.Path;

/**
 * 2021/10/25 17:06 星期一<br/>
 * 基础的实现
 *
 * @author xuMingHai
 */
public class ReactiveBaseExecutor implements ReactiveExecutor {

    private final ReactiveFileDao reactiveFileDao;

    private final ReactiveRecycleDao reactiveRecycleDao;

    public ReactiveBaseExecutor(ReactiveFileDao reactiveFileDao, ReactiveRecycleDao reactiveRecycleDao) {
        this.reactiveFileDao = reactiveFileDao;
        this.reactiveRecycleDao = reactiveRecycleDao;
    }

    /**
     * 默认参数请求的文件列表获取
     *
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<ListResponse>> list() {
        return reactiveFileDao.list().toEntity(ListResponse.class);
    }

    /**
     * 自定义请求参数的文件列表获取
     *
     * @param listRequest 文件请求参数
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<ListResponse>> list(ListRequest listRequest) {
        return reactiveFileDao.list(listRequest).toEntity(ListResponse.class);
    }

    /**
     * 根据文件名搜索文件
     *
     * @param fileName 文件名
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<SearchResponse>> search(String fileName) {
        return reactiveFileDao.search(fileName).toEntity(SearchResponse.class);
    }

    /**
     * 根据指定的文件名和文件类型搜索文件
     *
     * @param fileName     文件名
     * @param categoryEnum 文件类型
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<SearchResponse>> search(String fileName, CategoryEnum categoryEnum) {
        return reactiveFileDao.search(fileName, categoryEnum).toEntity(SearchResponse.class);
    }

    /**
     * 根据指定的文件名和文件类型搜索文件
     *
     * @param searchRequest 自定义搜索请求参数
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<SearchResponse>> search(SearchRequest searchRequest) {
        return reactiveFileDao.search(searchRequest).toEntity(SearchResponse.class);
    }

    /**
     * 获取指定文件的信息
     *
     * @param fileId 文件ID
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<BaseItem>> get(String fileId) {
        return reactiveFileDao.get(fileId).toEntity(BaseItem.class);
    }

    /**
     * 获取文件的下载地址信息
     *
     * @param fileId 文件ID
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<DownloadUrlResponse>> getDownloadUrl(String fileId) {
        return reactiveFileDao.getDownloadUrl(fileId).toEntity(DownloadUrlResponse.class);
    }

    /**
     * 下载文件，支持分段下载，断点续传
     *
     * @param fileId      文件ID
     * @param httpHeaders 表示 HTTP 请求头
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<Resource>> downloadFile(String fileId, HttpHeaders httpHeaders) {
        return reactiveFileDao.downloadFile(fileId, httpHeaders);
    }

    /**
     * 创建文件夹
     *
     * @param parentFileId  父目录ID
     * @param name          文件夹名
     * @param checkNameEnum 同名策略
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<CreateFolderResponse>> createFolder(String parentFileId, String name, CheckNameEnum checkNameEnum) {
        return reactiveFileDao.createFolder(parentFileId, name, checkNameEnum).toEntity(CreateFolderResponse.class);
    }

    /**
     * 创建文件夹，使用默认的同名策略，自动重命名
     *
     * @param parentFileId 父目录ID
     * @param name         文件夹名
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<CreateFolderResponse>> createFolder(String parentFileId, String name) {
        return reactiveFileDao.createFolder(parentFileId, name).toEntity(CreateFolderResponse.class);
    }

    /**
     * 创建文件夹，使用默认的同名策略，自动重命名，使用默认的顶级目录
     *
     * @param name 文件夹名
     * @return 异步响应体
     */
    @Override
    public Mono<ResponseEntity<CreateFolderResponse>> createFolder(String name) {
        return reactiveFileDao.createFolder(name).toEntity(CreateFolderResponse.class);
    }

    /**
     * 上传文件（支持快传和零拷贝）
     *
     * @param parentFileId  父目录ID
     * @param path          文件路径
     * @param checkNameEnum 同名策略
     * @return 上传文件的响应
     */
    @Override
    public Mono<CreateFileResponse> uploadFile(String parentFileId, Path path, CheckNameEnum checkNameEnum) {
        return reactiveFileDao.uploadFile(parentFileId, path, checkNameEnum);
    }

    /**
     * 上传文件，使用默认的同名策略，自动重命名（支持快传和零拷贝）
     *
     * @param parentFileId 父目录ID
     * @param path         文件路径
     * @return 上传文件的响应
     */
    @Override
    public Mono<CreateFileResponse> uploadFile(String parentFileId, Path path) {
        return reactiveFileDao.uploadFile(parentFileId, path);
    }

    /**
     * 上传文件，使用默认的顶级目录、同名策略，自动重命名（支持快传和零拷贝）
     *
     * @param path 文件路径
     * @return 上传文件的响应
     */
    @Override
    public Mono<CreateFileResponse> uploadFile(Path path) {
        return reactiveFileDao.uploadFile(path);
    }

    @Override
    public Mono<ResponseEntity<Void>> trash(String fileId) {
        return reactiveRecycleDao.trash(fileId).toBodilessEntity();
    }

    @Override
    public Mono<ResponseEntity<BaseItem>> update(UpdateRequest updateRequest) {
        return reactiveFileDao.update(updateRequest)
                .toEntity(BaseItem.class);
    }

    @Override
    public Mono<ResponseEntity<BaseItem>> update(String fileId, String name) {
        return reactiveFileDao.update(fileId, name)
                .toEntity(BaseItem.class);
    }
}
